home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / lang_c / cug191 / cflow.c < prev    next >
C/C++ Source or Header  |  1986-06-09  |  7KB  |  326 lines

  1. /*                                  CFLOW.C
  2.     This program identifies all function calls within a function
  3. */
  4.  
  5. #define FALSE   0
  6. #define TRUE    !FALSE
  7. #define ERROR   -1
  8.  
  9. #include        "stdio.h"
  10. /*
  11. #include        "process.h"
  12. #include        "string.h"
  13. #include        "ctype.h"
  14. */
  15.  
  16. /*
  17. void    modules( void );
  18. void    comment( void );
  19. void    lookbak( int );
  20. void    comout( char * );
  21. int     modname( void );
  22. int     unreserved( void );
  23. int     flowchar( char );
  24. int     ischar( char );
  25. int     fgets_sp( void );
  26. */
  27. void    modules(  );
  28. void    comment(  );
  29. void    lookbak(  );
  30. void    comout(  );
  31. int     modname(  );
  32. int     unreserved(  );
  33. int     flowchar(  );
  34. int     ischar(  );
  35. int     fgets_sp(  );
  36.  
  37.  
  38. FILE    *file_pointer;       /* input file pointer */
  39.  
  40. int     open_braces;      /* keep track of open_braces of open "{"s */
  41. char    module_name[100]; /* module name buffer */
  42.  
  43. char    input_buffer[256];  /* source input line buffer */
  44. int     curchar; /* current character in input line buffer array subscript */
  45.  
  46.  
  47. void main( argc, argv )
  48. int     argc;
  49. char    *argv[];
  50. {
  51.     printf("\nCFLOW --> function declarations and calls in C source");
  52.     printf("\n Modified by Jon R. Herbold"); 
  53.  
  54.     if (argc != 2)
  55.         {
  56.         printf( "\nusage: cflow [infilename.ext] " ); 
  57.         exit( 1 );
  58.         }
  59.  
  60.     if( ( file_pointer = fopen( argv[1], "r" ) ) == FALSE )
  61.         {
  62.         printf( "\nCan't open %s\n", argv[1] );
  63.         exit( 1 );
  64.         }
  65.  
  66.     printf( "\nSource file: %s", argv[1] );
  67.  
  68.     modules( ); 
  69.     fclose( file_pointer );
  70. }
  71.  
  72.  
  73.  
  74.  
  75.  
  76. void modules( )    /* find function declarations and calls */
  77. {
  78.     int     j;
  79.     char    c;
  80.     int     decl;   /* module declaration line flag */
  81.     int     lastlin = FALSE; /* last line of file flag */
  82.     int     quoted = FALSE;  /* within " quotes */
  83.     int     header = FALSE;  /* within function header (before 1st '{') */
  84.  
  85.     open_braces = 0;
  86.  
  87.     do 
  88.         {
  89.         lastlin = fgets_sp( );    /* read a line of source */
  90.         decl = FALSE;  /* assume nothing */
  91.         while( input_buffer[curchar] ) /* read for significant characters */
  92.             {
  93.             comment( );  /* strip any comments */
  94.  
  95.             c = input_buffer[curchar];
  96.  
  97.             /* read for significant characters */
  98.             /* skip double quoted strings */
  99.             if( c == '\042' )
  100.                 quoted = !quoted;
  101.  
  102.             if( !quoted )
  103.                 {
  104.                 switch( c )
  105.                     { 
  106.  
  107.                 case '{' : 
  108.                     open_braces++;
  109.                     header = FALSE;
  110.                     break;
  111.                 case '}' : 
  112.                     open_braces--;
  113.                     break; 
  114.                 case '(' : /* "(" always follows function call or declaration*/
  115.                     if( !ischar( input_buffer[curchar-1] ) ) 
  116.                         break;
  117.                     lookbak( curchar );
  118.                     j = modname( );
  119.                     if( !j )
  120.                         break;
  121.                     else
  122.                         decl = TRUE;
  123.                     if( j == 2 ) 
  124.                         header = TRUE; 
  125.                     break;
  126.                 default : 
  127.                     break;
  128.                     }
  129.                 }
  130.  
  131.             curchar++;     /* next character */
  132.             }
  133.  
  134.         comout( input_buffer );    /* display argument declarations */
  135.         } 
  136.     while( lastlin );    /*  = 0 if last line */
  137. }
  138.  
  139.  
  140.  
  141.  
  142.  
  143. /* return TRUE if entering comment, FALSE if exiting */
  144. void comment( )
  145. {
  146.     int     in_comment = 0;  /* comment flag */
  147.  
  148.     if( input_buffer[curchar] == '/' && input_buffer[curchar+1] == '*' )
  149.         {
  150.         in_comment++;
  151.         while( in_comment )
  152.             {
  153.             if( !input_buffer[curchar] )
  154.                 fgets_sp( );
  155.             if( input_buffer[curchar-1]=='*' && input_buffer[curchar]=='/' )
  156.                 in_comment--;
  157.             curchar++;
  158.             }
  159.         }
  160. }
  161.  
  162.  
  163.  
  164.  
  165.  
  166. /* look back from position n in string.  called with n indicating '('.
  167.    determine function module_name  */
  168. void lookbak( n )
  169. int     n;
  170. {
  171.     int     i;
  172.  
  173.     while( !ischar( input_buffer[n] ) )
  174.         {
  175.         if( n == 0 )
  176.             break;
  177.         --n;
  178.         }
  179.  
  180.     while( ischar( input_buffer[n-1] ) )    /* find leading blank */
  181.         {
  182.         if( n == 0 )
  183.             break;
  184.         --n;
  185.         }
  186.  
  187.     /* save module_name */
  188.     /* include variable declarations if module declaration */
  189.     i = 0;
  190.     if( open_braces == 0 )
  191.         {
  192.         while( input_buffer[n] )      /* full line if declaration */
  193.             module_name[i++] = input_buffer[n++];
  194.         }
  195.     else
  196.         {
  197.         while( ischar( input_buffer[n] ) )      /* function call within function */
  198.             module_name[i++] = input_buffer[n++];
  199.         }
  200.  
  201.     module_name[i] = '\0';
  202.  
  203.     comout( module_name ); /* remove comment from module_name string */
  204. }
  205.  
  206.  
  207.  
  208.  
  209.  
  210. /* terminate string at comment */
  211. void comout( s )
  212. char *s;
  213. {
  214.     char c; 
  215.  
  216.     while( c = *s++ ) 
  217.         if( c == '/' )
  218.             if( *s == '*' )
  219.                 {
  220.                 --s;
  221.                 *s++ = '\n';
  222.                 *s = '\0';
  223.                 break;
  224.                 }
  225. }
  226.  
  227.  
  228.  
  229.  
  230.  
  231. /* display module name with indentation according to { open_braces */
  232. /* returns 0 if not module, 1 if call within module, 2 if    */
  233. /* module declaration  */
  234. int modname( )
  235. {
  236.     int     j;
  237.  
  238.     if( unreserved( ) )
  239.         {  /* test if builtin like while */
  240.         if( open_braces == 0 )
  241.             {
  242.             printf( "\n}\n\n\n\n" );
  243.             comout( input_buffer );
  244.             printf( "%s{", input_buffer );
  245.             return( 2 );
  246.             }
  247.         else
  248.             {
  249.             printf( "\n" );
  250.             for( j=0; j < open_braces; ++j ) 
  251.                 printf( "  " );
  252.             printf( "%s()", module_name );
  253.             return( 1 );
  254.             }
  255.         }
  256.     return( 0 );
  257. }
  258.  
  259.  
  260.  
  261.  
  262.  
  263. /* test for names that are operators not functions */
  264. int unreserved( )
  265. {
  266.     if( !strcmp( module_name, "return" ) )
  267.         return( 0 );
  268.     else if( !strcmp( module_name, "if" ) )
  269.         return( 0 );
  270.     else if( !strcmp( module_name, "while" ) )
  271.         return( 0 );
  272.     else if( !strcmp( module_name, "for" ) )
  273.         return( 0 );
  274.     else if( !strcmp( module_name, "switch" ) )
  275.         return( 0 );
  276.     else
  277.         return( 1 );
  278. }
  279.  
  280.  
  281.  
  282.  
  283.  
  284. /* test if character is one that program tracks */
  285. int flowchar( c )
  286. char c;
  287. {
  288.     return( (c == '{' || c == '}' || c == '\"' ) ? TRUE : FALSE );
  289.  
  290.  
  291.  
  292.  
  293.  
  294. /* test for character */
  295. int ischar( c )
  296. char c;
  297. {
  298.     return( ( (c>='A' && c<='z') || (c>='0' && c<='9') ) ? TRUE : FALSE );
  299. }
  300.  
  301.  
  302.  
  303.  
  304.  
  305. /* read a line of source */
  306. int fgets_sp( )
  307. {
  308.     int  ch;
  309.     char *s;
  310.  
  311.     s = &input_buffer[0];
  312.     while( ( ch = getc( file_pointer ) ) != EOF )
  313.         {
  314.         *s++ = (char)ch;
  315.         if( ch == '\n' )
  316.             {
  317.             *s = '\0';
  318.             curchar = 0;
  319.             return( TRUE );
  320.             }
  321.         }
  322.     *s = '\0';
  323.     return( FALSE );
  324.